package com.jeesite.modules.stock.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.jeesite.common.lang.StringUtils;
import com.jeesite.modules.dp.dao.stocktmp.DpTmpjsonDao;
import com.jeesite.modules.dp.entity.stocktmp.DpTmpjson;
import com.jeesite.modules.utils.NVL;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;

/**
 * "mb": [ { "tiaojianchildlist": [] } ] }
 **/
public class StockFilterSqlBuilder {

    private DpTmpjsonDao dpTmpjsonDao = null;

    static final Map<String, String> conditionRef = new HashMap<String, String>() {
        {
            put("0", ">");
            put("1", "=");
            put("2", "<");
            put("3", ">=");
            put("4", "<=");
        }
    };

    public StockFilterSqlBuilder(DpTmpjsonDao dpTmpjsonDao) {
        this.dpTmpjsonDao = dpTmpjsonDao;
    }

    private DpTmpjson getTmpById(String id) {
        DpTmpjson entity = new DpTmpjson();
        entity.setId(id);
        return dpTmpjsonDao.get(entity);
    }

    private int findIndex(String[] arr, String data) {
        for (int i = 0; i < arr.length; i++) {
            if (arr[i].equals(data)) {
                return i;
            }
        }
        return -1;
    }

    private String valueConvert(String value, String amountunit, String zbsearchunit) {
        if (StringUtils.isBlank(value)) {
            return value;
        }
        String numberRegex = "\\d+(\\.\\d*)?";
        if (!Pattern.matches(numberRegex, value)) {
            return value;
        }
        if (StringUtils.isBlank(amountunit) || StringUtils.isBlank(zbsearchunit)) {
            return value;
        }
        String[] priceUnits = {"YUAN", "WAN_YUAN", "YI_YUAN", "WANYI_YUAN"};
        String[] percentUnits = {"PERCENT_DOT", "PERCENT_INT"};

        long[] priteRates = {1, 10000, 100000000L, 1000000000000L};
        int[] percentRates = {1, 100};

        int priceValueIndex = findIndex(priceUnits, amountunit);
        int priceSeachValueIndex = findIndex(priceUnits, zbsearchunit);

        if (priceValueIndex > -1 && priceSeachValueIndex > -1) {

            long valueRate = priteRates[priceValueIndex];
            long zbsearchRate = priteRates[priceSeachValueIndex];

            double divde = zbsearchRate * 1.0 / valueRate;

            double newValue = new BigDecimal(value)
                    .multiply(BigDecimal.valueOf(divde).setScale(4, RoundingMode.HALF_UP))
                    .setScale(4, RoundingMode.HALF_UP).doubleValue();

            return String.valueOf(newValue);
        }

        int percentValueIndex = findIndex(percentUnits, amountunit);
        int percentSearchValueIndex = findIndex(percentUnits, zbsearchunit);

        if (percentValueIndex > -1 && percentSearchValueIndex > -1) {
            long valueRate = percentRates[percentValueIndex];
            long zbsearchRate = percentRates[percentSearchValueIndex];

            double divde = zbsearchRate * 1.0 / valueRate;

            double newValue = new BigDecimal(value).divide(BigDecimal.valueOf(divde), RoundingMode.HALF_UP)
                    .setScale(4, RoundingMode.HALF_UP).doubleValue();

            return String.valueOf(newValue);
        }

        return value;
    }

    private String appendSqlCondition(JSONArray conditionItems, int index) {
        int size = conditionItems.size();

        StringBuilder sqlContent = new StringBuilder();
        for (int i = 0; i < size; i++) {
            JSONObject conditionItem = conditionItems.getJSONObject(i);
            String columnKey = conditionItem.getString("zbkey");
            String condition = conditionItem.getString("zbcomparefuhao");
            String value = conditionItem.getString("zbcomparevalue");
            String valueType = conditionItem.getString("valuetype");
            String zbsearchunit = conditionItem.getString("zbsearchunit");
            String amountunit = conditionItem.getString("amountunit");
            String zbcomparetype = conditionItem.getString("zbcomparetype");
            String zbbeilv = NVL.nvlIfBlank(conditionItem.getString("zbbeilv"), "1");

            String tmpid = conditionItem.getString("tmpid");

            if (!"BOOL".equals(valueType)) {
                value = valueConvert(value, amountunit, zbsearchunit);
            } else {
                value = "1";
                condition = "1";
            }
            if ("0".equals(zbcomparetype)) {
                value = "a." + value;
            }
            if (StringUtils.isBlank(tmpid)) {
                sqlContent.append("a.").append(columnKey).append(conditionRef.get(condition)).append(value).append("*").append(zbbeilv);
            } else {
                DpTmpjson tmp = getTmpById(tmpid);
                if (tmp == null || StringUtils.isBlank(tmp.getTmpjson())) {
                    continue;
                }
                sqlContent.append(buildTiaoJianWhere(tmp.getTmpjson()));
            }
            if (index == 0) {
                sqlContent.append(" and ");
            } else {
                sqlContent.append(" or ");
            }
        }
        if (sqlContent.toString().endsWith(" and ")) {
            sqlContent = new StringBuilder(sqlContent.substring(0, sqlContent.length() - " and ".length()));
        }
        if (sqlContent.toString().endsWith(" or ")) {
            sqlContent = new StringBuilder(sqlContent.substring(0, sqlContent.length() - " or ".length()));
        }

        if (!StringUtils.isBlank(sqlContent.toString())) {
            return " (" + sqlContent + ") and ";
        }
        return "";
    }

    /**
     * 示例：
     *
     * @param tiaojianList 条件json
     * @return 构建完成的SQL
     */
    public String buildTiaoJianWhere(String tiaojianList) {
        if (StringUtils.isBlank(tiaojianList)) {
            return "";
        }
        StringBuilder sql = new StringBuilder();
        JSONArray list = JSON.parseArray(tiaojianList);
        for (int i = 0; i < list.size(); i++) {
            JSONObject item = list.getJSONObject(i);
            JSONArray conditionItems = item.getJSONArray("tiaojianchildlist");
            if (!conditionItems.isEmpty()) {
                sql.append(appendSqlCondition(conditionItems, i));
            }
        }
        if (sql.toString().endsWith(" and ")) {
            sql = new StringBuilder(sql.substring(0, sql.length() - " and ".length()));
        }
        return sql.toString();
    }
}
